<!DOCTYPE html>
<HTML>
<HEAD><meta name="viewport" content="width=device-width, initial-scale=1">
<Title>Simple Real-Time Chart</Title>
<link type='text/css' rel='Stylesheet' href="maxchartapi.css" />
</HEAD>
<body bgcolor="#FFFFFF" text="#000000" topmargin="0" leftmargin="0" rightmargin="0" marginwidth="0" marginheight="0">
<p class="heading0">ChartDirector 7.0 (Java Edition)</p>
<p class="heading1">Simple Real-Time Chart</p>
<hr class="separator">
<div class="content"><img src="images/realtimedemo_web.png" width='784' height='419'><br><br>
This sample program demonstrates a real-time chart with configurable chart update rate, in which the chart image is updated via streaming.<br><br>
The chart is updated by calling <a href="JsChartViewer.streamUpdate.htm">JsChartViewer.streamUpdate</a> on the browser side. This method sends a "stream update request" to the server to update the chart image. The charting code in the server always draws the chart using the most updated data. By using a timer to call JsChartViewer.streamUpdate periodically, we can get a real time chart.<br><br>
On the server side, <a href="WebChartViewer.isStreamRequest.htm">WebChartViewer.isStreamRequest</a> is used to determine if the request is a normal request or is a stream update request. In the latter case, <a href="WebChartViewer.streamChart.htm">WebChartViewer.streamChart</a> is used to stream the updated chart to the browser and the script terminates immediately.<br><br>
Note that the streaming method used in this example only updates the chart image, but not the image map or the <a href="jschartmodel.htm">Javascript Chart Model</a>, so the chart does not have tooltips or track cursor features. See <a href="realtimetrackweb.htm">Real-Time Chart with Track Line</a> for an alternative method that can support tooltips and track cursors.
</div><p class="heading1a">Source Code Listing</p><div class="content">
<b>[JSP Version]</b> jspdemo/realtimedemo.jsp
<div class='codeblock'><code class='pre'>&lt;%@page import="ChartDirector.*, java.util.*" %&gt;
&lt;%
//
// Data to draw the chart. In this demo, the data buffer will be filled by a random data generator.
// In real life, the data is probably stored in a buffer (eg. a database table, a text file, or some
// global memory) and updated by other means.
//

// We use a data buffer to emulate the last 240 samples.
int sampleSize = 240;
double[] dataSeries1 = new double[sampleSize];
double[] dataSeries2 = new double[sampleSize];
double[] dataSeries3 = new double[sampleSize];
Date[] timeStamps = new Date[sampleSize];

// Our pseudo random number generator
double firstDate = new Date().getTime() / 1000 - timeStamps.length;
for(int i = 0; i &lt; timeStamps.length; ++i) {
    double p = firstDate + i;
    timeStamps[i] = new Date((long)p * 1000);
    dataSeries1[i] = Math.cos(p * 2.1) * 10 + 1 / (Math.cos(p) * Math.cos(p) + 0.01) + 20;
    dataSeries2[i] = 100 * Math.sin(p / 27.7) * Math.sin(p / 10.1) + 150;
    dataSeries3[i] = 100 * Math.cos(p / 6.7) * Math.cos(p / 11.9) + 150;
}

// Create an XYChart object 600 x 270 pixels in size, with light grey (f4f4f4) background, black
// (000000) border, 1 pixel raised effect, and with a rounded frame.
XYChart c = new XYChart(600, 270, 0xf4f4f4, 0x000000, 0);
c.setRoundedFrame();

// Set the plotarea at (55, 62) and of size 520 x 175 pixels. Use white (ffffff) background. Enable
// both horizontal and vertical grids by setting their colors to grey (cccccc). Set clipping mode to
// clip the data lines to the plot area.
c.setPlotArea(55, 62, 520, 175, 0xffffff, -1, -1, 0xcccccc, 0xcccccc);
c.setClipping();

// Add a title to the chart using 15pt Times New Roman Bold Italic font, with a light grey (dddddd)
// background, black (000000) border, and a glass like raised effect.
c.addTitle("Field Intensity at Observation Satellite", "Times New Roman Bold Italic", 15
    ).setBackground(0xdddddd, 0x000000, Chart.glassEffect());

// Add a legend box at the top of the plot area with 9pt Arial Bold font. We set the legend box to
// the same width as the plot area and use grid layout (as opposed to flow or top/down layout). This
// distributes the 3 legend icons evenly on top of the plot area.
LegendBox b = c.addLegend2(55, 33, 3, "Arial Bold", 9);
b.setBackground(Chart.Transparent, Chart.Transparent);
b.setWidth(520);

// Configure the y-axis with a 10pt Arial Bold axis title
c.yAxis().setTitle("Intensity (V/m)", "Arial Bold", 10);

// Configure the x-axis to auto-scale with at least 75 pixels between major tick and 15 pixels
// between minor ticks. This shows more minor grid lines on the chart.
c.xAxis().setTickDensity(75, 15);

// Set the axes width to 2 pixels
c.xAxis().setWidth(2);
c.yAxis().setWidth(2);

// Set the x-axis label format
c.xAxis().setLabelFormat("{value|hh:nn:ss}");

// Create a line layer to plot the lines
LineLayer layer = c.addLineLayer2();

// The x-coordinates are the timeStamps.
layer.setXData(timeStamps);

// The 3 data series are used to draw 3 lines. Here we put the latest data values as part of the
// data set name, so you can see them updated in the legend box.
layer.addDataSet(dataSeries1, 0xff0000, c.formatValue(dataSeries1[dataSeries1.length - 1],
    "Alpha: &lt;*bgColor=FFCCCC*&gt; {value|2} "));
layer.addDataSet(dataSeries2, 0x00cc00, c.formatValue(dataSeries2[dataSeries2.length - 1],
    "Beta: &lt;*bgColor=CCFFCC*&gt; {value|2} "));
layer.addDataSet(dataSeries3, 0x0000ff, c.formatValue(dataSeries3[dataSeries3.length - 1],
    "Gamma: &lt;*bgColor=CCCCFF*&gt; {value|2} "));

// Output the chart
WebChartViewer viewer = new WebChartViewer(request, "chart1");
viewer.setChart(c, Chart.SVG);

// Check if is a stream request to update the chart
if (viewer.isStreamRequest()) {
    // Stream the updated chart to the browser
    viewer.streamChart(response);
    return;
}
%&gt;
&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
    &lt;title&gt;Simple Real-Time Chart&lt;/title&gt;
    &lt;script type="text/javascript" src="cdjcv.js"&gt;&lt;/script&gt;
&lt;/head&gt;
&lt;body style="margin:0px"&gt;
&lt;table cellspacing="0" cellpadding="0" border="0"&gt;
    &lt;tr&gt;
        &lt;td align="right" colspan="2" style="background:#000088; color:#ffff00; padding:0px 4px 2px 0px;"&gt;
            &lt;a style="color:#FFFF00; font:italic bold 10pt Arial; text-decoration:none" href="http://www.advsofteng.com/"&gt;
                Advanced Software Engineering
            &lt;/a&gt;
        &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr valign="top"&gt;
        &lt;td style="width:130px; background:#c0c0ff; border-right:black 1px solid; border-bottom:black 1px solid;"&gt;
            &lt;br /&gt;
            &lt;br /&gt;
            &lt;div style="font:12px Verdana; padding:10px;"&gt;
                &lt;b&gt;Update Period&lt;/b&gt;&lt;br /&gt;
                &lt;select id="UpdatePeriod" style="width:110px"&gt;
                    &lt;option value="5"&gt;5&lt;/option&gt;
                    &lt;option value="10" selected="selected"&gt;10&lt;/option&gt;
                    &lt;option value="20"&gt;20&lt;/option&gt;
                    &lt;option value="30"&gt;30&lt;/option&gt;
                    &lt;option value="60"&gt;60&lt;/option&gt;
                &lt;/select&gt;
                &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;
                &lt;b&gt;Time Remaining&lt;/b&gt;&lt;br /&gt;
                &lt;div style="width:108px; border:#888888 1px inset;"&gt;
                    &lt;div style="margin:3px" id="TimeRemaining"&gt;0&lt;/div&gt;
                &lt;/div&gt;
            &lt;/div&gt;
        &lt;/td&gt;
        &lt;td&gt;
            &lt;div style="font: bold 20pt Arial; margin:5px 0px 0px 5px;"&gt;
                Simple Real-Time Chart
            &lt;/div&gt;
            &lt;hr style="border:solid 1px #000080" /&gt;
            &lt;div style="padding:0px 5px 5px 10px"&gt;
                &lt;!-- ****** Here is the chart image ****** --&gt;
                &lt;%=viewer.renderHTML(response)%&gt;
            &lt;/div&gt;
        &lt;/td&gt;
    &lt;/tr&gt;
&lt;/table&gt;
&lt;script type="text/javascript"&gt;

//
// Executes once every second to update the countdown display. Updates the chart when the countdown reaches 0.
//
function timerTick()
{
    // Get the update period and the time left
    var updatePeriod = parseInt(document.getElementById("UpdatePeriod").value);
    var timeLeft = Math.min(parseInt(document.getElementById("TimeRemaining").innerHTML), updatePeriod) - 1;

    if (timeLeft == 0)
        // Can update the chart now
        JsChartViewer.get('&lt;%=viewer.getId()%&gt;').streamUpdate();
    else if (timeLeft &lt; 0)
        // Reset the update period
        timeLeft += updatePeriod;

    // Update the countdown display
    document.getElementById("TimeRemaining").innerHTML = timeLeft;
}
window.setInterval("timerTick()", 1000);

&lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;</code></div></div><br>
<hr class="separator"><div class="copyright">&copy; 2022 Advanced Software Engineering Limited. All rights reserved.</div></body>
</HTML>
